bitkeeper revision 1.669 (3ff9eb5e0IQ4kkvTcwivJg9RViDQ6g)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 5 Jan 2004 22:55:26 +0000 (22:55 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 5 Jan 2004 22:55:26 +0000 (22:55 +0000)
xl_vbd.c, xl_block.h, xl_block.c, xen_block.c:
  Fix device numbers passed to Xen from Xenolinux - strip partition bits when appropriate.

xen/drivers/block/xen_block.c
xenolinux-2.4.23-sparse/arch/xeno/drivers/block/xl_block.c
xenolinux-2.4.23-sparse/arch/xeno/drivers/block/xl_block.h
xenolinux-2.4.23-sparse/arch/xeno/drivers/block/xl_vbd.c

index b000d365d0b1e5f05c130f2a78d21c71ddb7bc33..b3aa086f0659ce3d5cd28b9b29ac160c7b302dfa 100644 (file)
@@ -463,13 +463,6 @@ static void dispatch_rw_block_io(struct task_struct *p,
                         req->device); 
                 goto bad_descriptor;
             }
-
-           /*
-             * Clear any 'partition' bits in the device id. This works because
-             * IDE ignores the partition bits anyway. Only SCSI needs this
-             * hack, and we know that always requires the four LSBs cleared.
-             */
-           phys_seg[nr_psegs].dev = req->device & 0xFFF0;
             new_segs = 1;
         }
         
index ca11a114dfdc91089eb4d41c04f07063801b8500..8271654f1dab7dacf69fc1ec45eea346434168e2 100644 (file)
@@ -223,16 +223,17 @@ int xenolinux_block_revalidate(kdev_t dev)
     }
     spin_unlock_irqrestore(&io_request_lock, flags);
 
-    for ( i = gd->nr_real - 1; i >= 0; i-- )
+    for ( i = gd->max_p - 1; i >= 0; i-- )
     {
         invalidate_device(dev+i, 1);
         gd->part[MINOR(dev+i)].start_sect = 0;
-        gd->part[MINOR(dev+i)].nr_sects = 0;
+        gd->part[MINOR(dev+i)].nr_sects   = 0;
+        gd->sizes[MINOR(dev+i)]           = 0;
     }
 
     /* XXX Should perhaps revalidate VBDs here */
 
-    grok_partitions(gd, disk_nr, gd->nr_real, capacity);
+    grok_partitions(gd, disk_nr, gd->max_p, capacity);
 
     return 0;
 }
@@ -282,6 +283,14 @@ static int hypervisor_request(unsigned long   id,
          */
         sector_number += gd->part[MINOR(device)].start_sect;
 
+        /*
+         * If this unit doesn't consist of virtual (i.e., Xen-specified)
+         * partitions then we clear the partn bits from the device number.
+         */
+        if ( !(gd->flags[MINOR(device)>>gd->minor_shift] & 
+               GENHD_FL_VIRT_PARTNS) )
+            device &= ~(gd->max_p - 1);
+
         if ( (sg_operation == operation) &&
              (sg_dev == device) &&
              (sg_next_sect == sector_number) )
index c4cd7ec44e37ea63f84bf4a2807ac622eb87d6c4..9c6dcea5224e1be6a6318e8d5d0060f2e2af27ac 100644 (file)
@@ -39,6 +39,9 @@
 #define DPRINTK_IOCTL(_f, _a...) ((void)0)
 #endif
 
+/* Private gendisk->flags[] values. */
+#define GENHD_FL_XENO        2 /* Is unit a Xen block device?  */
+#define GENHD_FL_VIRT_PARTNS 4 /* Are unit partitions virtual? */
 
 /*
  * We have one of these per vbd, whether ide, scsi or 'other'.
index 2b65705083444467e285892355bbaad94122754f..d4e01f73d86b8a890e12c21ee61c98311c12671c 100644 (file)
@@ -8,12 +8,11 @@
 #include "xl_block.h"
 #include <linux/blk.h>
 
-#define GENHD_FL_XENO     2
-
-/* For convenience we distinguish between ide, scsi and 'other' (i.e. 
-** potentially combinations of the two) in the naming scheme and in a 
-** few other places (like default readahead, etc). 
-*/
+/*
+ * For convenience we distinguish between ide, scsi and 'other' (i.e.
+ * potentially combinations of the two) in the naming scheme and in a few 
+ * other places (like default readahead, etc).
+ */
 #define XLIDE_MAJOR_NAME  "hd"
 #define XLSCSI_MAJOR_NAME "sd"
 #define XLVBD_MAJOR_NAME "xvd"
@@ -31,7 +30,7 @@
 #define XLVBD_PARTN_SHIFT  6    /* amount to shift minor to get 'real' minor */
 #define XLVBD_MAX_PART    (1 << XLVBD_PARTN_SHIFT) /* minors per 'other' vbd */
 
-/* the below are for the use of the generic drivers/block/ll_rw_block.c code */
+/* The below are for the generic drivers/block/ll_rw_block.c code. */
 static int xlide_blksize_size[256];
 static int xlide_hardsect_size[256];
 static int xlide_max_sectors[256];
@@ -61,7 +60,7 @@ static struct block_device_operations xlvbd_block_fops =
  */
 int __init xlvbd_init(xen_disk_info_t *xdi)
 {
-    int i, result, max_part; 
+    int i, j, result, max_part; 
     struct gendisk *gd = NULL;
     kdev_t device; 
     unsigned short major, minor, partno; 
@@ -134,7 +133,7 @@ int __init xlvbd_init(xen_disk_info_t *xdi)
                 continue; 
             }
 
-            if( is_ide )
+            if ( is_ide )
             { 
                 blksize_size[major]  = xlide_blksize_size;
                 hardsect_size[major] = xlide_hardsect_size;
@@ -224,14 +223,37 @@ int __init xlvbd_init(xen_disk_info_t *xdi)
         gd->flags[minor >> gd->minor_shift] |= GENHD_FL_XENO;
         
         if ( partno != 0 )
-        { 
+        {
+            /*
+             * If this was previously set up as a real disc we will have set 
+             * up partition-table information. Virtual partitions override 
+             * 'real' partitions, and the two cannot coexist on a device.
+             */
+            if ( gd->sizes[minor & ~(max_part-1)] != 0 )
+            {
+                kdev_t dev = device & ~(max_part-1);
+                for ( j = max_part - 1; j >= 0; j-- )
+                {
+                    invalidate_device(dev+j, 1);
+                    gd->part[MINOR(dev+j)].start_sect = 0;
+                    gd->part[MINOR(dev+j)].nr_sects   = 0;
+                    gd->sizes[MINOR(dev+j)]           = 0;
+                }
+                printk(KERN_ALERT
+                       "Virtual partitions found for /dev/%s - ignoring any "
+                       "real partition information we may have found.\n",
+                       disk_name(gd, MINOR(device), buf));
+            }
+
             /* Need to skankily setup 'partition' information */
-            gd->part[partno].start_sect = 0; 
-            gd->part[partno].nr_sects   = xdi->disks[i].capacity; 
-            gd->sizes[partno]           = xdi->disks[i].capacity; 
+            gd->part[minor].start_sect = 0; 
+            gd->part[minor].nr_sects   = xdi->disks[i].capacity; 
+            gd->sizes[minor]           = xdi->disks[i].capacity; 
+
+            gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS;
         }
         else
-        { 
+        {
             /* Some final fix-ups depending on the device type */
             switch ( XD_TYPE(xdi->disks[i].info) )
             { 
@@ -248,8 +270,16 @@ int __init xlvbd_init(xen_disk_info_t *xdi)
                         "floppy"), disk_name(gd, MINOR(device), buf)); 
                 break; 
 
-            case XD_TYPE_DISK: 
-                register_disk(gd, device, gd->nr_real, &xlvbd_block_fops, 
+            case XD_TYPE_DISK:
+                /* Only check partitions on real discs (not virtual!). */
+                if ( gd->flags[minor>>gd->minor_shift] & GENHD_FL_VIRT_PARTNS )
+                {
+                    printk(KERN_ALERT
+                           "Skipping partition check on virtual /dev/%s\n",
+                           disk_name(gd, MINOR(device), buf));
+                    break;
+                }
+                register_disk(gd, device, gd->max_p, &xlvbd_block_fops, 
                               xdi->disks[i].capacity);
                 break;